home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 25
/
Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso
/
Aminet
/
dev
/
debug
/
Blowup.lha
/
source
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-18
|
8KB
|
415 lines
/*
* $Id: main.c 1.6 1998/04/18 15:44:40 olsen Exp olsen $
*
* :ts=4
*
* Blowup -- Catches and displays task errors
*
* Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
* Public Domain
*/
#ifndef _GLOBAL_H
#include "global.h"
#endif /* _GLOBAL_H */
/******************************************************************************/
#include "Blowup_rev.h"
/******************************************************************************/
#include "blowupsemaphore.h"
/******************************************************************************/
const STRPTR VersTag = VERSTAG;
/******************************************************************************/
STATIC BOOL ShowBannerMessage = TRUE;
/******************************************************************************/
STATIC struct BlowupSemaphore * BlowupSemaphore;
STATIC BOOL BlowupSemaphoreCreated;
/******************************************************************************/
STATIC struct BlowupSemaphore *
FindBlowupSemaphore(VOID)
{
struct BlowupSemaphore * bs;
/* look for the semaphore; this call must be made under Forbid() */
bs = (struct BlowupSemaphore *)FindSemaphore(BLOWUPSEMAPHORENAME);
return(bs);
}
STATIC VOID
DeleteBlowupSemaphore(struct BlowupSemaphore * bs)
{
if(bs != NULL)
{
/* gain exclusive access to the semaphore and remove it */
ObtainSemaphore((struct SignalSemaphore *)bs);
RemSemaphore((struct SignalSemaphore *)bs);
ReleaseSemaphore((struct SignalSemaphore *)bs);
/* release the memory allocated for the semaphore */
FreeMem(bs,sizeof(*bs));
}
}
STATIC struct BlowupSemaphore *
CreateBlowupSemaphore(VOID)
{
struct BlowupSemaphore * bs;
/* allocate memory for the semaphore and initialize */
bs = AllocMem(sizeof(*bs),MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR);
if(bs != NULL)
{
bs->bs_SignalSemaphore.ss_Link.ln_Name = bs->bs_SemaphoreName;
bs->bs_SignalSemaphore.ss_Link.ln_Pri = 1;
bs->bs_Version = BLOWUPSEMAPHOREVERSION;
strcpy(bs->bs_SemaphoreName,BLOWUPSEMAPHORENAME);
bs->bs_Owner = FindTask(NULL);
bs->bs_ARegCheck = &ARegCheck;
bs->bs_DRegCheck = &DRegCheck;
bs->bs_StackCheck = &StackCheck;
bs->bs_StackLines = &StackLines;
/* add the semaphore to the public list */
AddSemaphore((struct SignalSemaphore *)bs);
}
return(bs);
}
/******************************************************************************/
STATIC VOID
Cleanup(VOID)
{
/* delete the semaphore, if we created it */
if(BlowupSemaphoreCreated)
{
DeleteBlowupSemaphore(BlowupSemaphore);
BlowupSemaphore = NULL;
}
/* release the semaphore; this is done only if we did
* not create the semaphore ourselves
*/
if(BlowupSemaphore != NULL)
{
ReleaseSemaphore((struct SignalSemaphore *)BlowupSemaphore);
BlowupSemaphore = NULL;
}
/* shut down the timer */
DeleteTimer();
/* close intuition.library */
if(IntuitionBase != NULL)
{
CloseLibrary(IntuitionBase);
IntuitionBase = NULL;
}
/* close utility.library, if this is necessary */
#if !defined(__SASC) || defined(_M68020)
{
if(UtilityBase != NULL)
{
CloseLibrary(UtilityBase);
UtilityBase = NULL;
}
}
#endif
}
STATIC BOOL
Setup(VOID)
{
LONG error = OK;
int i;
/* Kickstart 2.04 or higher required */
if(SysBase->LibNode.lib_Version < 37)
{
const STRPTR message = "This program requires Kickstart 2.04 or better.\n";
Write(Output(),message,strlen(message));
return(FAILURE);
}
/* determine the program name */
StrcpyN(sizeof(ProgramName),ProgramName,VERS);
for(i = strlen(ProgramName) - 1 ; i >= 0 ; i--)
{
if(ProgramName[i] == ' ')
{
ProgramName[i] = '\0';
break;
}
}
/* set up the busy semaphore */
InitSemaphore(&BusySemaphore);
/* open intuition.library */
IntuitionBase = OpenLibrary("intuition.library",37);
if(IntuitionBase == NULL)
{
Printf("%s: Could not open intuition.library V37.\n",ProgramName);
return(FAILURE);
}
/* open utility.library, if this is necessary */
#if !defined(__SASC) || defined(_M68020)
{
UtilityBase = OpenLibrary("utility.library",37);
if(UtilityBase == NULL)
{
Printf("%s: Could not open utility.library V37.\n",ProgramName);
return(FAILURE);
}
}
#endif
/* allocate the timer data */
if(CreateTimer() == -1)
{
Printf("%s: Could not create timer.\n",ProgramName);
return(FAILURE);
}
/* initialize default options */
DRegCheck = FALSE;
ARegCheck = FALSE;
StackCheck = FALSE;
StackLines = 2;
/* rendezvous with the global semaphore or create it */
Forbid();
BlowupSemaphore = FindBlowupSemaphore();
if(BlowupSemaphore != NULL)
{
ObtainSemaphore((struct SignalSemaphore *)BlowupSemaphore);
}
else
{
BlowupSemaphore = CreateBlowupSemaphore();
if(BlowupSemaphore != NULL)
{
BlowupSemaphoreCreated = TRUE;
}
else
{
error = ERROR_NO_FREE_STORE;
}
}
Permit();
if(error == OK)
{
struct RDArgs * rda;
/* these are the command line parameters, later
* filled in by ReadArgs() below
*/
struct
{
SWITCH Off;
SWITCH Parallel;
SWITCH NoBanner;
SWITCH DRegCheck;
SWITCH NoDRegCheck;
SWITCH ARegCheck;
SWITCH NoARegCheck;
SWITCH StackCheck;
SWITCH NoStackCheck;
NUMBER StackLines;
} params;
/* this is the command template, as required by ReadArgs() below;
* its contents must match the "params" data structure above
*/
const STRPTR cmdTemplate =
"QUIT=OFF/S,"
"PARALLEL/S,"
"QUIET=NOBANNER/S,"
"DREGCHECK/S,"
"NODREGCHECK/S,"
"AREGCHECK/S,"
"NOAREGCHECK/S,"
"STACKCHECK/S,"
"NOSTACKCHECK/S,"
"STACKLINES/K/N";
memset(¶ms,0,sizeof(params));
/* read the command line parameters */
rda = ReadArgs((STRPTR)cmdTemplate,(LONG *)¶ms,NULL);
if(rda != NULL)
{
struct BlowupSemaphore * bs = BlowupSemaphore;
/* enable data register check? */
if(params.DRegCheck)
{
(*bs->bs_DRegCheck) = TRUE;
}
/* disable data register check? */
if(params.NoDRegCheck)
{
(*bs->bs_DRegCheck) = FALSE;
}
/* enable address register check? */
if(params.ARegCheck)
{
(*bs->bs_ARegCheck) = TRUE;
}
/* disable address register check? */
if(params.NoARegCheck)
{
(*bs->bs_ARegCheck) = FALSE;
}
/* enable stack check? */
if(params.StackCheck)
{
(*bs->bs_StackCheck) = TRUE;
}
/* disable stack check? */
if(params.NoStackCheck)
{
(*bs->bs_StackCheck) = FALSE;
}
/* set the number of stack lines to display? */
if(params.StackLines != NULL)
{
LONG value;
value = (*params.StackLines);
if(value < 0)
value = 0;
(*bs->bs_StackLines) = value;
}
/* do not show the banner message? */
if(params.NoBanner)
{
ShowBannerMessage = FALSE;
}
/* enable parallel port output? */
if(params.Parallel)
{
ChooseParallelOutput();
}
/* shut down Blowup? */
if(params.Off)
{
if(NOT BlowupSemaphoreCreated)
{
Signal(bs->bs_Owner,SIG_Stop);
}
}
FreeArgs(rda);
}
else
{
error = IoErr();
}
}
if(error == OK)
{
return(SUCCESS);
}
else
{
PrintFault(error,ProgramName);
return(FAILURE);
}
}
/******************************************************************************/
int
main(
int argc,
char ** argv)
{
int result = RETURN_FAIL;
/* set up all the data we need */
if(Setup())
{
result = RETURN_OK;
/* do something useful if we are the owner of the semaphore */
if(BlowupSemaphoreCreated)
{
BOOL done;
/* show the welcome message */
if(ShowBannerMessage)
{
DPrintf("%s -- Catches and displays task errors\n",ProgramName);
DPrintf("Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>\n");
DPrintf("Public Domain\n");
}
Forbid();
/* plant the monitoring patches */
AddPatches();
done = FALSE;
do
{
/* wait for something to happen */
if(FLAG_IS_SET(Wait(SIG_Stop),SIG_Stop))
{
done = TRUE;
/* wait until it is safe to quit */
ObtainSemaphore(&BusySemaphore);
DPrintf("%s terminated.\n",ProgramName);
}
}
while(NOT done);
/* remove the patches again */
RemovePatches();
Permit();
}
}
Cleanup();
return(result);
}